home *** CD-ROM | disk | FTP | other *** search
/ Risc World 5 / Risc World 5.iso / SOFTWARE / Issue3 / Games / xrick / !xrick / src / c / draw < prev    next >
Text File  |  2004-06-24  |  14KB  |  684 lines

  1. /*
  2.  * xrick/src/draw.c
  3.  *
  4.  * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net). All rights reserved.
  5.  *
  6.  * The use and distribution terms for this software are contained in the file
  7.  * named README, which can be found in the root of this distribution. By
  8.  * using this software in any fashion, you are agreeing to be bound by the
  9.  * terms of this license.
  10.  *
  11.  * You must not remove this notice, or any other, from this software.
  12.  */
  13.  
  14. /*
  15.  * NOTES
  16.  *
  17.  * This is the only file which accesses the video. Anything calling d_*
  18.  * function should be video-independant.
  19.  *
  20.  * draw.c draws into a 320x200 or 0x0140x0xc8 8-bits depth frame buffer,
  21.  * using the CGA 2 bits color codes. It is up to the video to figure out
  22.  * how to display the frame buffer. Whatever draw.c does, does not show
  23.  * until the screen is explicitely refreshed.
  24.  *
  25.  * The "screen" is the whole 0x0140 by 0x00c8 screen, coordinates go from
  26.  * 0x0000,0x0000 to 0x013f,0x00c7.
  27.  *
  28.  * The "map" is a 0x0100 by 0x0140 rectangle that represents the active
  29.  * game area.
  30.  *
  31.  * Relative to the screen, the "map" is located at 0x0020,-0x0040 : the
  32.  * "map" is composed of two hidden 0x0100 by 0x0040 rectangles (one at the
  33.  * top and one at the bottom) and one visible 0x0100 by 0x00c0 rectangle (in
  34.  * the middle).
  35.  *
  36.  * The "map screen" is the visible rectangle ; it is a 0x0100 by 0xc0
  37.  * rectangle located at 0x0020,0x00.
  38.  *
  39.  * Coordinates can be relative to the screen, the map, or the map screen.
  40.  *
  41.  * Coordinates can be expressed in pixels. When relative to the map or the
  42.  * map screen, they can also be expressed in tiles, the map being composed
  43.  * of rows of 0x20 tiles of 0x08 by 0x08 pixels.
  44.  */
  45.  
  46. #include "system.h"
  47. #include "game.h"
  48. #include "draw.h"
  49.  
  50. #include "sysvid.h"
  51. #include "sprites.h"
  52. #include "tiles.h"
  53. #include "maps.h"
  54. #include "rects.h"
  55. #include "img.h"
  56.  
  57.  
  58. /*
  59.  * counters positions (pixels, screen)
  60.  */
  61. #ifdef GFXPC
  62. #define DRAW_STATUS_SCORE_X 0x28
  63. #define DRAW_STATUS_LIVES_X 0xE8
  64. #define DRAW_STATUS_Y 0x08
  65. #endif
  66. #define DRAW_STATUS_BULLETS_X 0x68
  67. #define DRAW_STATUS_BOMBS_X 0xA8
  68. #ifdef GFXST
  69. #define DRAW_STATUS_SCORE_X 0x20
  70. #define DRAW_STATUS_LIVES_X 0xF0
  71. #define DRAW_STATUS_Y 0
  72. #endif
  73.  
  74.  
  75. /*
  76.  * public vars
  77.  */
  78. U8 *draw_tllst;    /* pointer to tiles list */
  79. #ifdef GFXPC
  80. U16 draw_filter;   /* CGA colors filter */
  81. #endif
  82. U8 draw_tilesBank; /* tile number offset */
  83. rect_t draw_STATUSRECT = {
  84.   DRAW_STATUS_SCORE_X, DRAW_STATUS_Y,
  85.   DRAW_STATUS_LIVES_X + 6 * 8 - DRAW_STATUS_SCORE_X, 8,
  86.   NULL
  87. };
  88. rect_t draw_SCREENRECT = { 0, 0, SYSVID_WIDTH, SYSVID_HEIGHT, NULL };
  89.  
  90.  
  91. /*
  92.  * private vars
  93.  */
  94. static U8 *fb;     /* frame buffer pointer */
  95.  
  96.  
  97. /*
  98.  * Set the frame buffer pointer
  99.  *
  100.  * x, y: position (pixels, screen)
  101.  */
  102. void
  103. draw_setfb(U16 x, U16 y)
  104. {
  105.   fb = sysvid_fb + x + y * SYSVID_WIDTH;
  106. }
  107.  
  108.  
  109. /*
  110.  * Clip to map screen
  111.  *
  112.  * x, y: position (pixels, map) CHANGED clipped
  113.  * width, height: dimension CHANGED clipped
  114.  * return: TRUE if fully clipped, FALSE if still (at least partly) visible
  115.  */
  116. U8
  117. draw_clipms(S16 *x, S16 *y, U16 *width, U16 *height)
  118. {
  119.   if (*x < 0) {
  120.     if (*x + *width < 0)
  121.       return TRUE;
  122.     else {
  123.       *width += *x;
  124.       *x = 0;
  125.     }
  126.   }
  127.   else {
  128.     if (*x > 0x0100)
  129.       return TRUE;
  130.     else if (*x + *width > 0x0100) {
  131.       *width = 0x0100 - *x;
  132.     }
  133.   }
  134.  
  135.   if (*y < DRAW_XYMAP_SCRTOP) {
  136.     if ((*y + *height) < DRAW_XYMAP_SCRTOP)
  137.       return TRUE;
  138.     else {
  139.       *height += *y - DRAW_XYMAP_SCRTOP;
  140.       *y = DRAW_XYMAP_SCRTOP;
  141.     }
  142.   }
  143.   else {
  144.     if (*y >= DRAW_XYMAP_HBTOP)
  145.       return TRUE;
  146.     else if (*y + *height > DRAW_XYMAP_HBTOP)
  147.       *height = DRAW_XYMAP_HBTOP - *y;
  148.   }
  149.  
  150.   return FALSE;
  151. }
  152.  
  153.  
  154. /*
  155.  * Draw a list of tiles onto the frame buffer
  156.  * start at position indicated by fb ; at the end of each (sub)list,
  157.  * perform a "carriage return + line feed" i.e. go back to the initial
  158.  * position then go down one tile row (8 pixels)
  159.  *
  160.  * ASM 1e33
  161.  * fb: CHANGED (see above)
  162.  * draw_tllst: CHANGED points to the element following 0xfe/0xff end code
  163.  */
  164. void
  165. draw_tilesList(void)
  166. {
  167.   U8 *t;
  168.  
  169.   t = fb;
  170.   while (draw_tilesSubList() != 0xFE) {  /* draw sub-list */
  171.     t += 8 * SYSVID_WIDTH;  /* go down one tile i.e. 8 lines */
  172.     fb = t;
  173.   }
  174. }
  175.  
  176.  
  177. /*
  178.  * Draw a list of tiles onto the frame buffer -- same as draw_tilesList,
  179.  * but accept an immediate string as parameter. Note that the string needs
  180.  * to be properly terminated with 0xfe (\376) and 0xff (\377) chars.
  181.  */
  182. void
  183. draw_tilesListImm(U8 *list)
  184. {
  185.   draw_tllst = list;
  186.   draw_tilesList();
  187. }
  188.  
  189.  
  190. /*
  191.  * Draw a sub-list of tiles onto the frame buffer
  192.  * start at position indicated by fb ; leave fb pointing to the next
  193.  * tile to the right of the last tile drawn
  194.  *
  195.  * ASM 1e41
  196.  * fpb: CHANGED (see above)
  197.  * draw_tllst: CHANGED points to the element following 0xfe/0xff end code
  198.  * returns: end code (0xfe : end of list ; 0xff : end of sub-list)
  199.  */
  200. U8
  201. draw_tilesSubList()
  202. {
  203.   U8 i;
  204.  
  205.   i = *(draw_tllst++);
  206.   while (i != 0xFF && i != 0xFE) {  /* while not end */
  207.     draw_tile(i);  /* draw tile */
  208.     i = *(draw_tllst++);
  209.   }
  210.   return i;
  211. }
  212.  
  213.  
  214. /*
  215.  * Draw a tile
  216.  * at position indicated by fb ; leave fb pointing to the next tile
  217.  * to the right of the tile drawn
  218.  *
  219.  * ASM 1e6c
  220.  * tlnbr: tile number
  221.  * draw_filter: CGA colors filter
  222.  * fb: CHANGED (see above)
  223.  */
  224. void
  225. draw_tile(U8 tileNumber)
  226. {
  227.   U8 i, k, *f;
  228.  
  229. #ifdef GFXPC
  230.   U16 x;
  231. #endif
  232.  
  233. #ifdef GFXST
  234.   U32 x;
  235. #endif
  236.  
  237.   f = fb;  /* frame buffer */
  238.   for (i = 0; i < 8; i++) {  /* for all 8 pixel lines */
  239.  
  240. #ifdef GFXPC
  241.     x = tiles_data[draw_tilesBank][tileNumber][i] & draw_filter;
  242.     /*
  243.      * tiles / perform the transformation from CGA 2 bits
  244.      * per pixel to frame buffer 8 bits per pixels
  245.      */
  246.     for (k = 8; k--; x >>= 2)
  247.       f[k] = x & 3;
  248.     f += SYSVID_WIDTH;  /* next line */
  249. #endif
  250.  
  251. #ifdef GFXST
  252.   x = tiles_data[draw_tilesBank][tileNumber][i];
  253.   /*
  254.    * tiles / perform the transformation from ST 4 bits
  255.    * per pixel to frame buffer 8 bits per pixels
  256.    */
  257.   for (k = 8; k--; x >>= 4)
  258.     f[k] = x & 0x0F;
  259.   f += SYSVID_WIDTH;  /* next line */
  260. #endif
  261.  
  262.   }
  263.  
  264.   fb += 8;  /* next tile */
  265. }
  266.  
  267. /*
  268.  * Draw a sprite
  269.  *
  270.  * ASM 1a09
  271.  * nbr: sprite number
  272.  * x, y: sprite position (pixels, screen)
  273.  * fb: CHANGED
  274.  */
  275. #ifdef GFXPC
  276. void
  277. draw_sprite(U8 nbr, U16 x, U16 y)
  278. {
  279.   U8 i, j, k, *f;
  280.   U16 xm = 0, xp = 0;
  281.  
  282.   draw_setfb(x, y);
  283.  
  284.   for (i = 0; i < 4; i++) {  /* for each tile column */
  285.     f = fb;  /* frame buffer */
  286.     for (j = 0; j < 0x15; j++) {  /* for each pixel row */
  287.       xm = sprites_data[nbr][i][j].mask;  /* mask */
  288.       xp = sprites_data[nbr][i][j].pict;  /* picture */
  289.       /*
  290.        * sprites / perform the transformation from CGA 2 bits
  291.        * per pixel to frame buffer 8 bits per pixels
  292.        */
  293.       for (k = 8; k--; xm >>= 2, xp >>= 2)
  294.     f[k] = (f[k] & (xm & 3)) | (xp & 3);
  295.       f += SYSVID_WIDTH;
  296.     }
  297.     fb += 8;
  298.   }
  299. }
  300. #endif
  301.  
  302.  
  303. /*
  304.  * Draw a sprite
  305.  *
  306.  * foobar
  307.  */
  308. #ifdef GFXST
  309. void
  310. draw_sprite(U8 number, U16 x, U16 y)
  311. {
  312.   U8 i, j, k, *f;
  313.   U16 g;
  314.   U32 d;
  315.  
  316.   draw_setfb(x, y);
  317.   g = 0;
  318.   for (i = 0; i < 0x15; i++) { /* rows */
  319.     f = fb;
  320.     for (j = 0; j < 4; j++) { /* cols */
  321.       d = sprites_data[number][g++];
  322.       for (k = 8; k--; d >>= 4)
  323.     if (d & 0x0F) f[k] = (f[k] & 0xF0) | (d & 0x0F);
  324.       f += 8;
  325.     }
  326.     fb += SYSVID_WIDTH;
  327.   }
  328. }
  329. #endif
  330.  
  331.  
  332. /*
  333.  * Draw a sprite
  334.  *
  335.  * NOTE re-using original ST graphics format
  336.  */
  337. #ifdef GFXST
  338. void
  339. draw_sprite2(U8 number, U16 x, U16 y, U8 front)
  340. {
  341.   U32 d = 0;   /* sprite data */
  342.   S16 x0, y0;  /* clipped x, y */
  343.   U16 w, h;    /* width, height */
  344.   S16 g,       /* sprite data offset*/
  345.     r, c,      /* row, column */
  346.     i,         /* frame buffer shifter */
  347.     im;        /* tile flag shifter */
  348.   U8 flg;      /* tile flag */
  349.  
  350.   x0 = x;
  351.   y0 = y;
  352.   w = 0x20;
  353.   h = 0x15;
  354.  
  355.   if (draw_clipms(&x0, &y0, &w, &h))  /* return if not visible */
  356.     return;
  357.  
  358.   g = 0;
  359.   draw_setfb(x0 - DRAW_XYMAP_SCRLEFT, y0 - DRAW_XYMAP_SCRTOP + 8);
  360.  
  361.   for (r = 0; r < 0x15; r++) {
  362.     if (r >= h || y + r < y0) continue;
  363.  
  364.     i = 0x1f;
  365.     im = x - (x & 0xfff8);
  366.     flg = map_eflg[map_map[(y + r) >> 3][(x + 0x1f)>> 3]];
  367.  
  368. #ifdef ENABLE_CHEATS
  369. #define LOOP(N, C0, C1) \
  370.     d = sprites_data[number][g + N]; \
  371.     for (c = C0; c >= C1; c--, i--, d >>= 4, im--) { \
  372.       if (im == 0) { \
  373.     flg = map_eflg[map_map[(y + r) >> 3][(x + c) >> 3]]; \
  374.     im = 8; \
  375.       } \
  376.       if (c >= w || x + c < x0) continue; \
  377.       if (!front && !game_cheat3 && (flg & MAP_EFLG_FGND)) continue; \
  378.       if (d & 0x0F) fb[i] = (fb[i] & 0xF0) | (d & 0x0F); \
  379.       if (game_cheat3) fb[i] |= 0x10; \
  380.     }
  381. #else
  382. #define LOOP(N, C0, C1) \
  383.     d = sprites_data[number][g + N]; \
  384.     for (c = C0; c >= C1; c--, i--, d >>= 4, im--) { \
  385.       if (im == 0) { \
  386.     flg = map_eflg[map_map[(y + r) >> 3][(x + c) >> 3]]; \
  387.     im = 8; \
  388.       } \
  389.       if (!front && (flg & MAP_EFLG_FGND)) continue; \
  390.       if (c >= w || x + c < x0) continue; \
  391.       if (d & 0x0F) fb[i] = (fb[i] & 0xF0) | (d & 0x0F); \
  392.     }
  393. #endif
  394.     LOOP(3, 0x1f, 0x18);
  395.     LOOP(2, 0x17, 0x10);
  396.     LOOP(1, 0x0f, 0x08);
  397.     LOOP(0, 0x07, 0x00);
  398.  
  399. #undef LOOP
  400.  
  401.     fb += SYSVID_WIDTH;
  402.     g += 4;
  403.   }
  404. }
  405.  
  406. #endif
  407.  
  408.  
  409. /*
  410.  * Draw a sprite
  411.  * align to tile column, determine plane automatically, and clip
  412.  *
  413.  * nbr: sprite number
  414.  * x, y: sprite position (pixels, map).
  415.  * fb: CHANGED
  416.  */
  417. #ifdef GFXPC
  418. void
  419. draw_sprite2(U8 number, U16 x, U16 y, U8 front)
  420. {
  421.   U8 k, *f, c, r, dx;
  422.   U16 cmax, rmax;
  423.   U16 xm = 0, xp = 0;
  424.   S16 xmap, ymap;
  425.  
  426.   /* align to tile column, prepare map coordinate and clip */
  427.   xmap = x & 0xFFF8;
  428.   ymap = y;
  429.   cmax = 0x20;  /* width, 4 tile columns, 8 pixels each */
  430.   rmax = 0x15;  /* height, 15 pixels */
  431.   dx = (x - xmap) * 2;
  432.   if (draw_clipms(&xmap, &ymap, &cmax, &rmax))  /* return if not visible */
  433.     return;
  434.  
  435.   /* get back to screen */
  436.   draw_setfb(xmap - DRAW_XYMAP_SCRLEFT, ymap - DRAW_XYMAP_SCRTOP);
  437.   xmap >>= 3;
  438.   cmax >>= 3;
  439.  
  440.   /* draw */
  441.   for (c = 0; c < cmax; c++) {  /* for each tile column */
  442.     f = fb;
  443.     for (r = 0; r < rmax; r++) {  /* for each pixel row */
  444.       /* check that tile is not hidden behind foreground */
  445. #ifdef ENABLE_CHEATS
  446.       if (front || game_cheat3 ||
  447.       !(map_eflg[map_map[(ymap + r) >> 3][xmap + c]] & MAP_EFLG_FGND)) {
  448. #else
  449.       if (front ||
  450.       !(map_eflg[map_map[(ymap + r) >> 3][xmap + c]] & MAP_EFLG_FGND)) {
  451. #endif
  452.     xp = xm = 0;
  453.     if (c > 0) {
  454.       xm |= sprites_data[number][c - 1][r].mask << (16 - dx);
  455.       xp |= sprites_data[number][c - 1][r].pict << (16 - dx);
  456.     }
  457.     else
  458.       xm |= 0xFFFF << (16 - dx);
  459.     if (c < cmax) {
  460.       xm |= sprites_data[number][c][r].mask >> dx;
  461.       xp |= sprites_data[number][c][r].pict >> dx;
  462.     }
  463.     else
  464.       xm |= 0xFFFF >> dx;
  465.     /*
  466.      * sprites / perform the transformation from CGA 2 bits
  467.      * per pixel to frame buffer 8 bits per pixels
  468.      */
  469.     for (k = 8; k--; xm >>= 2, xp >>= 2) {
  470.       f[k] = ((f[k] & (xm & 3)) | (xp & 3));
  471. #ifdef ENABLE_CHEATS
  472.       if (game_cheat3) f[k] |= 4;
  473. #endif
  474.     }
  475.       }
  476.       f += SYSVID_WIDTH;
  477.     }
  478.     fb += 8;
  479.   }
  480. }
  481. #endif
  482.  
  483.  
  484. /*
  485.  * Redraw the map behind a sprite
  486.  * align to tile column and row, and clip
  487.  *
  488.  * x, y: sprite position (pixels, map).
  489.  */
  490. void
  491. draw_spriteBackground(U16 x, U16 y)
  492. {
  493.   U8 r, c;
  494.   U16 rmax, cmax;
  495.   S16 xmap, ymap;
  496.   U16 xs, ys;
  497.  
  498.   /* aligne to column and row, prepare map coordinate, and clip */
  499.   xmap = x & 0xFFF8;
  500.   ymap = y & 0xFFF8;
  501.   cmax = (x - xmap == 0 ? 0x20 : 0x28);  /* width, 4 tl cols, 8 pix each */
  502.   rmax = (y & 0x04) ? 0x20 : 0x18;  /* height, 3 or 4 tile rows */
  503.   if (draw_clipms(&xmap, &ymap, &cmax, &rmax))  /* don't draw if fully clipped */
  504.     return;
  505.  
  506.   /* get back to screen */
  507.   xs = xmap - DRAW_XYMAP_SCRLEFT;
  508.   ys = ymap - DRAW_XYMAP_SCRTOP;
  509.   xmap >>= 3;
  510.   ymap >>= 3;
  511.   cmax >>= 3;
  512.   rmax >>= 3;
  513.  
  514.   /* draw */
  515.   for (r = 0; r < rmax; r++) {  /* for each row */
  516. #ifdef GFXPC
  517.     draw_setfb(xs, ys + r * 8);
  518. #endif
  519. #ifdef GFXST
  520.     draw_setfb(xs, 8 + ys + r * 8);
  521. #endif
  522.     for (c = 0; c < cmax; c++) {  /* for each column */
  523.       draw_tile(map_map[ymap + r][xmap + c]);
  524.     }
  525.   }
  526. }
  527.  
  528.  
  529. /*
  530.  * Draw entire map screen background tiles onto frame buffer.
  531.  *
  532.  * ASM 0af5, 0a54
  533.  */
  534. void
  535. draw_map(void)
  536. {
  537.   U8 i, j;
  538.  
  539.   draw_tilesBank = map_tilesBank;
  540.  
  541.   for (i = 0; i < 0x18; i++) {  /* 0x18 rows */
  542. #ifdef GFXPC
  543.     draw_setfb(0x20, (i * 8));
  544. #endif
  545. #ifdef GFXST
  546.     draw_setfb(0x20, 8 + (i * 8));
  547. #endif
  548.     for (j = 0; j < 0x20; j++)  /* 0x20 tiles per row */
  549.       draw_tile(map_map[i + 8][j]);
  550.   }
  551. }
  552.  
  553.  
  554. /*
  555.  * Draw status indicators
  556.  *
  557.  * ASM 0309
  558.  */
  559. void
  560. draw_drawStatus(void)
  561. {
  562.   S8 i;
  563.   U32 sv;
  564.   static U8 s[7] = {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfe};
  565.  
  566.   draw_tilesBank = 0;
  567.  
  568.   for (i = 5, sv = game_score; i >= 0; i--) {
  569.     s[i] = 0x30 + (U8)(sv % 10);
  570.     sv /= 10;
  571.   }
  572.   draw_tllst = s;
  573.  
  574.   draw_setfb(DRAW_STATUS_SCORE_X, DRAW_STATUS_Y);
  575.   draw_tilesList();
  576.  
  577.   draw_setfb(DRAW_STATUS_BULLETS_X, DRAW_STATUS_Y);
  578.   for (i = 0; i < game_bullets; i++)
  579.     draw_tile(TILES_BULLET);
  580.  
  581.   draw_setfb(DRAW_STATUS_BOMBS_X, DRAW_STATUS_Y);
  582.   for (i = 0; i < game_bombs; i++)
  583.     draw_tile(TILES_BOMB);
  584.  
  585.   draw_setfb(DRAW_STATUS_LIVES_X, DRAW_STATUS_Y);
  586.   for (i = 0; i < game_lives; i++)
  587.     draw_tile(TILES_RICK);
  588. }
  589.  
  590.  
  591. /*
  592.  * Draw info indicators
  593.  */
  594. #ifdef ENABLE_CHEATS
  595. void
  596. draw_infos(void)
  597. {
  598.   draw_tilesBank = 0;
  599.  
  600. #ifdef GFXPC
  601.   draw_filter = 0xffff;
  602. #endif
  603.  
  604.   draw_setfb(0x00, DRAW_STATUS_Y);
  605.   draw_tile(game_cheat1 ? 'T' : '@');
  606.   draw_setfb(0x08, DRAW_STATUS_Y);
  607.   draw_tile(game_cheat2 ? 'N' : '@');
  608.   draw_setfb(0x10, DRAW_STATUS_Y);
  609.   draw_tile(game_cheat3 ? 'V' : '@');
  610. }
  611. #endif
  612.  
  613.  
  614. /*
  615.  * Clear status indicators
  616.  */
  617. void
  618. draw_clearStatus(void)
  619. {
  620.   U8 i;
  621.  
  622. #ifdef GFXPC
  623.   draw_tilesBank = map_tilesBank;
  624. #endif
  625. #ifdef GFXST
  626.   draw_tilesBank = 0;
  627. #endif
  628.   draw_setfb(DRAW_STATUS_SCORE_X, DRAW_STATUS_Y);
  629.   for (i = 0; i < DRAW_STATUS_LIVES_X/8 + 6 - DRAW_STATUS_SCORE_X/8; i++) {
  630. #ifdef GFXPC
  631.     draw_tile(map_map[MAP_ROW_SCRTOP + (DRAW_STATUS_Y / 8)][i]);
  632. #endif
  633. #ifdef GFXST
  634.     draw_tile('@');
  635. #endif
  636.   }
  637. }
  638.  
  639. /*
  640.  * Draw a picture
  641.  */
  642. #ifdef GFXST
  643. void
  644. draw_pic(U16 x, U16 y, U16 w, U16 h, U32 *pic)
  645. {
  646.   U8 *f;
  647.   U16 i, j, k, pp;
  648.   U32 v;
  649.  
  650.   draw_setfb(x, y);
  651.   pp = 0;
  652.  
  653.   for (i = 0; i < h; i++) { /* rows */
  654.     f = fb;
  655.     for (j = 0; j < w; j += 8) {  /* cols */
  656.       v = pic[pp++];
  657.       for (k = 8; k--; v >>=4)
  658.     f[k] = v & 0x0F;
  659.       f += 8;
  660.     }
  661.     fb += SYSVID_WIDTH;
  662.   }
  663. }
  664. #endif
  665.  
  666.  
  667. /*
  668.  * Draw a bitmap
  669.  */
  670. void
  671. draw_img(img_t *i)
  672. {
  673.   U16 k;
  674.  
  675.   draw_setfb(0, 0);
  676.   if (i->ncolors > 0)
  677.     sysvid_setPalette(i->colors, i->ncolors);
  678.   for (k = 0; k < SYSVID_WIDTH * SYSVID_HEIGHT; k++)
  679.     fb[k] = i->pixels[k];
  680. }
  681.  
  682.  
  683. /* eof */
  684.